﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using ScrumFactory.Composition.ViewModel;
using ScrumFactory.Services;
using ScrumFactory.Composition;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Json;

namespace ScrumFactory.GooglePlugin.ViewModel {

    [Export(typeof(IPluginCommand))]
    public class GoogleTaskAddCommand : IPluginCommand {

        private IDialogService dialogs;
        private IBackgroundExecutor executor;
        private IAuthorizationService authorizator;
        private IEventAggregator aggregator;

        [ImportingConstructor]
        public GoogleTaskAddCommand(
            [Import] IDialogService dialogs,
            [Import] IBackgroundExecutor executor,
            [Import] IEventAggregator aggregator,
            [Import] IAuthorizationService authorizator) {
            
            this.dialogs = dialogs;
            this.executor = executor;
            this.authorizator = authorizator;
            this.aggregator = aggregator;

            aggregator.Subscribe<Task>(ScrumFactoryEvent.TaskAdded, OnNewTaskAdded);
            aggregator.Subscribe<Task>(ScrumFactoryEvent.TaskAssigneeChanged, OnNewTaskAdded);

            OnClickCommand = new DelegateCommand<object>(AddTaskToGoogle);
        }

        public int DisplayOrder {
            get {
                return 100;
            }
        }

        public System.Windows.Input.ICommand OnClickCommand {
            get;
            set;
        }

        public string MenuItemHeader {
            get {
                return Properties.Resources.Add_to_Goggle;
            }
        }

        public string MenuItemIconUrl {
            get {
                return "pack://application:,,,/ScrumFactory.GooglePlugin;component/Images/gtask_add.png";
            }
        }

        public bool IsCheckeable {
            get {
                return false;
            }
        }

        public bool IsChecked {
            get {
                return false;
            }
            set { }
        }

        public string ContainerViewModelClassName {
            get {
                return "ScrumFactory.Tasks.ViewModel.TaskViewModel";
            }
        }
        
        private void AddTaskToGoogle(dynamic o) {
            if (o == null)
                return;
            Task task = o.Task as Task;
            if (task == null)
                return;

            if (task.Status == (short)TaskStatus.DONE_TASK || task.Status == (short)TaskStatus.CANCELED_TASK)
                return;
            
            System.Windows.MessageBoxResult r =
                dialogs.ShowMessageBox(
                    Properties.Resources.Add_task_to_Google,
                    String.Format(Properties.Resources.Add_T_to_Google_Tasks, task.TaskName),                
                    System.Windows.MessageBoxButton.YesNo,
                    "pack://application:,,,/ScrumFactory.GooglePlugin;component/Images/gtask_add.png");

            if (r == System.Windows.MessageBoxResult.No)
                return;

            AddTask(task);
           
        }


        private void AddTask(Task task) {

            // only my tasks can be added
            if (authorizator.SignedMemberProfile == null || authorizator.SignedMemberProfile.MemberUId != task.TaskAssigneeUId) {
                dialogs.ShowAlertMessage(Properties.Resources.Could_not_add_task_to_Google, Properties.Resources.Only_tasks_assigned_to_you_can_be_added, null);
                return;
            }

            // create gTask
            string taskId = "";
            if(task.TaskInfo!=null)
                taskId = "#" + task.TaskInfo.ProjectNumber + "." + task.TaskInfo.BacklogItemNumber + "." + task.TaskNumber + "#";
            dynamic gTask = new JsonObject();

            gTask.title = task.TaskName;
            gTask.eta = taskId;
            gTask.due = System.DateTime.Now.AddHours((double)task.PlannedHours);
            if(task.TaskDetail!=null)
                gTask.notes = task.TaskDetail.Detail;
            
            // adds it            
            string errorMsg = null;
            
            executor.StartBackgroundTask(                
                () => {
                    System.Net.Http.HttpClient wc = new System.Net.Http.HttpClient();
                    wc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authorizator.SignedMemberToken);
                    try {
                        System.Net.Http.HttpResponseMessage msg = wc.Post("https://www.googleapis.com/tasks/v1/lists/@default/tasks", new ObjectContent<JsonObject>(gTask, JsonValueMediaTypeFormatter.DefaultMediaType));
                        if (!msg.IsSuccessStatusCode) {
                            string a = msg.Content.ReadAsString();
                            errorMsg = msg.StatusCode.ToString();
                        }
                    }
                    catch (Exception ex) {
                        errorMsg = ex.Message;
                    }
                },
                () => {
                    if (!String.IsNullOrEmpty(errorMsg))
                        dialogs.ShowAlertMessage(Properties.Resources.Could_not_add_task_to_Google, errorMsg, null);
                });

        }

        private bool AutoAddTask {
            get {
                return Properties.Settings.Default.AutoAddToGoogleTasks;
            }
        }

        private void OnNewTaskAdded(Task newTask) {
            if (!AutoAddTask)
                return;

            // only my tasks can be added
            if (authorizator.SignedMemberProfile == null || authorizator.SignedMemberProfile.MemberUId != newTask.TaskAssigneeUId)
                return;

            AddTask(newTask);
        }

    }
}
